from django.shortcuts import render
from rest_framework import status

from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from rest_framework.generics import ListAPIView
from rest_framework.response import Response
from rest_framework_jwt.views import ObtainJSONWebToken

from goods.models import SKU
from users.serializers import RegisterCreateUserSerializer
# Create your views here.

# 问题！！！
# 因为我们已经告知系统 子应用在apps中 不需要再添加apps
# from apps.users.models import Users

# 正确的
from users.models import Users



###########################################用户注册代码##############################################
#用户名验证
class RegisterUsernameView(APIView):

    """
    判断用户名是否存在
    1.让前端把用户名传递过来
    2.以get方式把用户名传递过来
    3.实现业务逻辑

    GET         users/usernames/username/

    GET          /users/usernames/(?P<username>\w{5,20})/count/
    """

    def get(self,request,username):

        # count = 0 没有
        # count = 1 注册过
        count = Users.objects.filter(username=username).count()


        #组织数据
        context = {
            'count':count,
            'username':username
        }


        return Response(context)



#手机号验证
class RegisterPhoneCountAPIView(APIView):
    def get(self,request,mobile):
        count=Users.objects.filter(mobile=mobile).count()
        context={
            'count':count,
            'mobile':mobile
        }
        return Response(context)





#用户注册
class RegisterCreateUserView(APIView):
    """
        1.我们需要让前端把 用户名，密码，确认密码，手机号，短信验证码，是否同意协议 传递过来
        2.后端接收参数，对参数进行校验
        3.数据入库
        4.返回响应

        get
        post        post相对于get而言 安全

        POST        /users/

        """
    def post(self,request):
        data=request.data
        # print(data)
        serializer=RegisterCreateUserSerializer(data=data)
        serializer.is_valid(raise_exception=True)


        serializer.save()

        # Users.objects.create(**validated_data)
        # 如果我们的data没有问题，就相当于下边的写发
        # data = {'username':xxx,'password2':xxx}
        # data 多余的字段删除掉
        # Users.objects.create(**data)

        # 4.返回响应
        # serializer.data 做什么？
        # 将对象转换为字典       序列化操作
        # user --> 字典中 key

        # print('done')
        return Response(serializer.data)




#####################RegisterCreateUserView可用二级视图####################

# from rest_framework.generics import GenericAPIView
# from rest_framework.mixins import CreateModelMixin
#
# class RegisterCreateUserView(CreateModelMixin,GenericAPIView):
#
#     serializer_class = RegisterCreateUserSerializer
#     def post(self,request):
#         return self.create(request)

#####################三级视图####################
#
# from rest_framework.generics import CreateAPIView
#
# class RegisterCreateUser2View(CreateAPIView):
#
#     serializer_class = RegisterCreateUserSerializer













########################用户中心页面代码####################################################################


from rest_framework.permissions import IsAuthenticated
from .serializers import UserInfoSerializer
# 1. 如果我们分析不出来就先继承自APIView
#   实现了功能之后，再对代码进行优化和封装
class UserCenterInfoView(APIView):
    #1.必须是登录用户才可以访问该页面
    #     2.获取用户信息， 直接返回就可以

    # 必须是登录用户才可以访问该页面
    permission_classes = [IsAuthenticated]
    def get(self,request):
        # 我们是采用的jwt token认证
        #         #前段把 token传递给我 我就知道谁登录
        #         # requst.user 就是 认证登录的用户

        user=request.user

        serializer=UserInfoSerializer(instance=user)

        return Response(serializer.data)


######################采用二级视图优化以上代码##########################

from rest_framework.generics import GenericAPIView
from rest_framework.mixins import RetrieveModelMixin

# class UserCenterInfoView(RetrieveModelMixin,GenericAPIView):
#
#     permission_classes = [IsAuthenticated]
#
#     queryset=Users.objects.all()
#     serializer_class = UserInfoSerializer
#
#
#     def get_object(self):
#         return self.request.user
#
#     def get(self,request):
#         return self.retrieve(request)





######################采用三级视图优化以上代码##########################

# from rest_framework.generics import RetrieveAPIView
#
# class UserCenterInfoView(RetrieveAPIView):
#
#     serializer_class = UserInfoSerializer
#     queryset = Users.objects.all()
#
#     def get_object(self):
#         return self.request.user




######################邮件视图函数#################################################

# from rest_framework.generics import UpdateAPIView
# from .serializers import EmailSerializer
# class UserUpdateEmailView(APIView):
#
#     """
#     1.用户在点击设置的时候，输入邮箱，点击保存的时候，前段应该将 邮件信息发送给后台
#     # 2. 后台接受到 邮件信息之后 需要进行校验，
#     # 3.校验完成之后对数据进行 保存操作
#     # 4. 保存之后要发送一封激活邮件
#     # 5. 返回响应
#
#     PUT     /users/email/
#
#     """
#
#     permission_classes = [IsAuthenticated]
#
#     def put(self,request):
#         # 1. 后台接受到 邮件信息之后 需要进行校验，
#         user = request.user
#
#         data = request.data
#
#         serializer = EmailSerializer(instance=user,data=data)
#
#         serializer.is_valid(raise_exception=True)
#
#         #.2校验完成之后对数据进行 保存操作
#         serializer.save()
#
#         #3.返回响应
#         return Response(serializer.data)
#



######################优化邮件视图函数#################################################
from rest_framework.generics import UpdateAPIView,GenericAPIView
from .serializers import EmailSerializer



class UserUpdateEmailView(UpdateAPIView):

    permission_classes = [IsAuthenticated]

    queryset = Users.objects.all()
    serializer_class = EmailSerializer


    def get_object(self):
        return self.request.user






#########################################################################################

from .serializers import AddressSerializer
from users.models import Address

class AddressView(APIView):


    permission_classes = [IsAuthenticated]

############################增加地址#######################################################3
    def post(self,request):

        data=request.data

        serializer=AddressSerializer(data=data,context={'request':request})

        serializer.is_valid(raise_exception=True)

        serializer.save()

        return Response(serializer.data)



############################################地址列表############################################

    def get(self,request):

        from users.models import Address

        addresslist=Address.objects.all()

        user=request.user

        serializer=AddressSerializer(addresslist,many=True)


        return Response({
            'user_id':user.id,
            'addresses':serializer.data,
            'limit':20,
            'default_address_id':user.default_address

        })





class AddressDetailView(APIView):
##################################删除地址#######################################################
    permission_classes = [IsAuthenticated]

    def delete(self,request,id):

        address=Address.objects.get(id=id)

        address.delete()

        return Response(status=status.HTTP_204_NO_CONTENT)



###############################修改信息###################################################################

    def put(self,request,id):

        address=Address.objects.get(id=id)

        data=request.data


        serializer=AddressSerializer(instance=address,data=data)

        serializer.is_valid(raise_exception=True)

        serializer.save()

        return Response(serializer.data)


##############################################################设置默认地址##################################################3
from users.serializers import Users
class DefaultAddressDetailView(APIView):
    def put(self,request,id):

        address=Address.objects.get(id=id)

        user=request.user

        user.default_address=address

        user.save()



        return Response({'message':'ok'},status=status.HTTP_200_OK)










#######################################################用户浏览记录############################################################


# 需要用户登录的

# 1. 在详情页面，我们需要让前端将 商品id，和用户信息传递给后台， 这样的话 才可以保存浏览记录

# 2. 展示浏览记录的时候，根据用户的id信息，查询指定的数据
#       数据的保存是可以保存在 数据库中的，但是我们的知识点设计的是 保存在Redis


from .serializers import UserHistorySerializer
from django_redis import get_redis_connection
class UserHistoryView(APIView):


    """
        1.实现用户浏览数据的入库操作
         1.1 让前端把 商品id，用户信息 发送给后端
         # 1.2 后端接受数据，并且对数据进行校验
         # 1.3 校验没有问题，数据入库（Redis）
         # 1.4 返回响应

        POST    /users/browerhistories/
        """

    permission_classes = [IsAuthenticated]

    # 我们是采用的jwt的认证方法，所以 需要让前端把token 传递过来
    # token是放在请求的header中

    # 商品id放在body中就可以
#####################################################在商品详情页储存商品ｉｄ##########################################
    def post(self,request):
        # 1.2 后端接受数据，并且对数据进行校验

        # print(request)

        data=request.data

        user=request.user

        serializer=UserHistorySerializer(data=data)

        serializer.is_valid(raise_exception=True)

        sku_id=serializer.data.get('sku_id')


        # 1.3 校验没有问题，数据入库（Redis）

        # 1.3.1连接redis

        redis_conn=get_redis_connection('history')


        # 1.3.2 把数据保存到redis中
        # 先删除可能存在的 sku_id
        redis_conn.lrem('history_%s'%user.id,0,sku_id)


        # 再添加
        redis_conn.lpush('history_%s'%user.id,sku_id)


        # 。1.3.3 只保留5个
        redis_conn.ltrim('history_%s'%user.id,0,4)


        return Response(serializer.data)




######################################################在个人中心页面获取浏览过的商品ｉｄ，根据ｉｄ获取数据###############################3
        # def get(self,request):
        #
        #     user=request.user
        #
        #     redis_conn=get_redis_connection('history')
        #
        #     ids=redis_conn.lrange('history_%s'%user.id,0,5)
        #
        #     print(ids)
        #
        #     skus=[]
        #
        #     for suk_id in ids:
        #         sku=SKU.objects.get(pk=suk_id)
        #         skus.append(sku)
        #
        #     from goods.serializers import SKUSerializer
        #
        #
        #     serializer=SKUSerializer(instance=skus,many=True)
        #
        #
        #     return Response(serializer.data)







    def get(self, request):
        # 1. 连接redis

        redis_conn = get_redis_connection('history')
        # 2. 获取浏览记录 [1,2,3]
        ids = redis_conn.lrange('history_%s' % request.user.id, 0, 5)

        # 3.根据id获取详细信息 [SKU,SKU,SKU]
        # sku_ids = SKU.objects.filter(pk__in=ids)
        # 如果采用in进行查询，我们的顺序就错乱了
        skus = []
        for sku_id in ids:
            sku = SKU.objects.get(pk=sku_id)

            skus.append(sku)

        # 4.将 对象列表进行序列化器的操作
        from goods.serializers import SKUSerializer
        serialzier = SKUSerializer(skus, many=True)
        # 5.返回响应
        return Response(serialzier.data)









#######################################重写Ｄｊａｎｇｏ封装好的登陆用的视图函数####################################################



from cart.utils import merge_cookie_to_redis

class UserAuthorizationView(ObtainJSONWebToken):

    def post(self, request):
        # 调用jwt扩展的方法，对用户登录的数据进行验证
        response = super().post(request)

        # 如果用户登录成功，进行购物车数据合并
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            # 表示用户登录成功
            user = serializer.validated_data.get("user")
            # 合并购物车
            #merge_cart_cookie_to_redis(request, user, response)
            response = merge_cookie_to_redis(request, user, response)

        return response
